//============================================================================================
/**
 * @file	evt_start.c
 * @brief	ポケスロン競技開始タイトルデモ
 * @author	Nozomu Saito -> Genya Hosaka(引継ぎ)
 */
//============================================================================================
#include "common.h"
#include "gflib/touchpanel.h"
#include "system/wipe.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/snd_play.h"
#include "system/pm_overlay.h"
#include "communication/wm_icon.h"

#include "msgdata/msg.naix"
#include "msgdata/msg_pokethlon.h"

//#include "../../pkthln_obj_common.h"
#include "../../pkthln_comm_pack.h"

#include "../event_se_def.h"
#include "../evt_logo.h"

#include "field/eventflag.h"
#include "field/evwkdef.h"
#include "fielddata/script/saveflag.h"

#include "../../../pokethlon_museum/museum_util.h"
#include "../../../pokethlon_museum/museum_obj.h"
#include "../../../pokethlon_museum/museum_bg.h"

#include "evt_start.h"

#include "pkth_evt_title.naix"
#include "pkth_title_NANR_LBLDEFS.h"

#define EVTCALL_HEAP_SIZE	(0x40000)

// 自分の席だけ、デバッグ処理
#if 0
	#ifdef DEBUG_ONLY_FOR_genya_hosaka
		#define EVT_START_DEBUG_MODE		///< defineされていればデバッグ機能ON
	#endif
#endif

FS_EXTERN_OVERLAY( pkthln_common );

//--------------------------------------------------------------
///	定数
//==============================================================
enum
{
	OBJ_DISTANCE = FX32_CONST(512), ///< 上下画面OBJ距離

	END_WAIT = 60 * 3,				///< 通信時のウェイト
	BG_IN_FRAME = 14,				///< BGが拡縮するフレーム数
	EVENT_BG_DIFF_Y = 4 * 8,		///< 通信時：BGがずれるY座標

	BMPWIN_OFS_X = 4,

	BG_FRM_M_BASE = GF_BGL_FRAME0_M,
	BG_FRM_M_BTN = GF_BGL_FRAME1_M,
	BG_FRM_M_TEXT = GF_BGL_FRAME2_M,
	BG_FRM_S_BASE = GF_BGL_FRAME0_S,
	BG_FRM_S_TEXT = GF_BGL_FRAME1_S,
	BG_FRM_S_EVTMSG  = GF_BGL_FRAME2_S,
	BG_FRM_S_EVT = GF_BGL_FRAME3_S,
	BG_USE_NUM = 7,
};

// -- 使用するBGテーブル
static const u8 c_BG_UseList[ BG_USE_NUM ] = {
	GF_BGL_FRAME0_M, GF_BGL_FRAME1_M, GF_BGL_FRAME2_M,
	GF_BGL_FRAME0_S, GF_BGL_FRAME1_S, GF_BGL_FRAME2_S, GF_BGL_FRAME3_S,
};

static const u8 c_BG_ModeList[ BG_USE_NUM ] = {
	GF_BGL_MODE_TEXT, GF_BGL_MODE_TEXT, GF_BGL_MODE_TEXT,
	GF_BGL_MODE_TEXT, GF_BGL_MODE_TEXT, GF_BGL_MODE_256X16, GF_BGL_MODE_256X16
};


//--------------------------------------------------------------
///	BMPWIN_ID
//==============================================================
enum
{
	BMPWIN_ID_M_POINT_CAP = 0,
	BMPWIN_ID_M_POINT_MSG,
	BMPWIN_ID_M_OPRCAP,
	BMPWIN_ID_M_OPRMSG_01,
	BMPWIN_ID_M_BTN_TRL,
	BMPWIN_ID_S_MATCH,
	BMPWIN_ID_S_SCORE_CAP,
	BMPWIN_ID_S_SCORE,
	// チュートリアル中のみ使用するBMPWIN
	BMPWIN_TUTORIAL_ID_TITLE,
	BMPWIN_TUTORIAL_ID_BTN_NEXT,
	BMPWIN_TUTORIAL_ID_BTN_RETURN,
	BMPWIN_TUTORIAL_ID_TEXT,
	BMPWIN_ID_MAX,
};

//--------------------------------------------------------------
///	OBJ用：リソースID
//==============================================================
enum {
	CHR_ID_M_COMMON = 0,
	CHR_ID_MAX,
};

enum {
	PAL_ID_M_COMMON = 0,
	PAL_ID_MAX,
};

enum {
	CEL_ID_COMMON = 0,
	CEL_ID_MAX,
};

enum {
	ANM_ID_COMMON = 0,
	ANM_ID_MAX,
};

enum {
	OBJ_ID_M_POINT = 0,
	OBJ_ID_M_PEN,
	OBJ_ID_M_OPERATE,
	OBJ_ID_M_TOUCH_ICON,
	OBJ_ID_COMMON_MAX,
	OBJ_ID_MAX = OBJ_ID_COMMON_MAX,
};

enum { ANM_OPERATE_MAX = 2, };

//--------------------------------------------------------------
///	メインワーク
//==============================================================
typedef struct EVT_START_tag
{
	PKTHLN_PTR		wk_main;
	GF_BGL_INI*		bgl;
	ARCHANDLE*		arc_ev_title;
	HEAPID			HeapID;

	CATS_SYS_PTR		csp;
	CATS_RES_PTR		crp;

	int next_phase;
	int	Counter;
	u8	ev_idx;
	u8	anm_seq;
	u8	match;
	BOOL b_comm;		///< 通信フラグ
	BOOL b_draw_score;	///< スコア描画フラグ
	BOOL b_bg_move;		///< BG移動フラグ

	MUSEUM_MSG_WORK*	wk_msg;

	EVT_LOGO_PTR		logo;
	CATS_ACT_PTR		cap[ OBJ_ID_MAX ];
}EVT_START;

// -- prototype --
static void VBlankFunc( void* work );
static void SetVramBank(void);
static BOOL CheckBgmVariable( u8 var_no , u8 check_val );
static u8 GetEventCode( PKTHLN_PTR work );
static BOOL GetMuseumFlag( PKTHLN_PTR ptr );
static void SceneInit( PKTHLN_PTR work );
static void BGLoad_LcdSub_Title( EVT_START_PTR ptr );
static void BGLoad_LcdSub_EvCapture( EVT_START_PTR ptr, int ev_idx );
static void InitBG(GF_BGL_INI * ini, HEAPID heapID);
static void SetBG(EVT_START_PTR ptr);
static void PrintStaticMessage_Init( EVT_START_PTR ptr );
static void PrintStaticMessage_Rule( EVT_START_PTR ptr );
static void PrintStaticMessage_Control( EVT_START_PTR ptr );
static void InitObj( EVT_START_PTR ptr );
static void ObjLoadRes( EVT_START_PTR ptr );
static void ObjProc( EVT_START_PTR ptr );
static void OBJ_SetViewMode( EVT_START_PTR ptr, int view_idx );
static void OBjRestart( EVT_START_PTR ptr );
static void ObjAddCommon( EVT_START_PTR ptr );
static void ObjSetOperateAnm( EVT_START_PTR ptr );
static void EventBgInit( EVT_START_PTR ptr );
static void EventBgStartUp( EVT_START_PTR ptr );
static void EventBgProc( EVT_START_PTR ptr );
static void Phase_SetNextReq( PKTHLN_PTR work, int next_phase );
static BOOL Phase_ChangeProc( PKTHLN_PTR work );
static void Phase_Init( PKTHLN_PTR work );
static BOOL EVT_START_Func_Phase_Init(PKTHLN_PTR work, u8 *seq);
static BOOL EVT_START_Func_Phase_Title(PKTHLN_PTR work, u8 *seq);
static BOOL EVT_START_Func_Phase_Rule(PKTHLN_PTR work, u8 *seq);
static BOOL EVT_START_Func_Phase_Control(PKTHLN_PTR work, u8 *seq);
static BOOL EVT_START_Func_Phase_End(PKTHLN_PTR work, u8 *seq);


enum {
	EVT_START_PHASE_INIT = 0,
	EVT_START_PHASE_TITLE,
	EVT_START_PHASE_RULE,
	EVT_START_PHASE_CONTROL,
	EVT_START_PHASE_END,
};

// -- phase table --
PKTHLN_FUNC EvtStartFuncTbl[] = {
	EVT_START_Func_Phase_Init,
	EVT_START_Func_Phase_Title,
	EVT_START_Func_Phase_Rule,
	EVT_START_Func_Phase_Control,
	EVT_START_Func_Phase_End,
};

//--------------------------------
// BMPWIN 関係
//--------------------------------
#define BMP_STRING_H ( 2 )

//===============================================================
// TITLE MAIN
//===============================================================
#define OPRMSG_LINE ( 3 )	///< 競技説明文の行数

//-- main
#define BMP_POINT_CAP_W	( 14 )
#define BMP_POINT_MSG_W ( 24 )
#define BMP_OPRCAP_W	( 14 )
#define BMP_OPRMSG_W	( 24 )
#define BMP_BTN_TRL_W	( 6 )

//-- main cgx
#define BMP_POINT_CAP_CGX	( 1 )
#define BMP_POINT_MSG_CGX	( BMP_POINT_CAP_CGX	+ BMP_POINT_CAP_W	* BMP_STRING_H )
#define BMP_OPRCAP_CGX		( BMP_POINT_MSG_CGX + BMP_POINT_MSG_W	* BMP_STRING_H )
#define BMP_OPRMSG_01_CGX	( BMP_OPRCAP_CGX	+ BMP_OPRCAP_W		* BMP_STRING_H )
#define BMP_BTN_TRL_CGX		( BMP_OPRMSG_01_CGX + BMP_OPRMSG_W		* BMP_STRING_H * OPRMSG_LINE )

//===============================================================
// TITLE SUB
//===============================================================
//-- sub
#define BMP_S_MATCH_W		( 14 )
#define BMP_S_SCORE_CAP_W	( 22 )
#define BMP_S_SCORE_W		( 22 )

//-- sub cgx
#define BMP_S_MATCH_CGX		( 1 )
#define BMP_S_SCORE_CAP_CGX	( BMP_S_MATCH_CGX		+ BMP_S_MATCH_W		* BMP_STRING_H )
#define BMP_S_SCORE_CGX		( BMP_S_SCORE_CAP_CGX	+ BMP_S_SCORE_CAP_W	* BMP_STRING_H )

#define BG_EVT_COMM_DEF_Y ( 5 )	///< 種目名のY座標(ハイスコア非表示時)

//===============================================================
// TUTORIAL MAIN
//===============================================================
// --- width
#define BMP_TRL_TITLE_W			( 12 )
#define BMP_TRL_BTN_NEXT_W		( 5 )
#define BMP_TRL_BTN_RETURN_W	( 5 )
#define BMP_TRL_TEXT_W			( 28 )

// --- cgx
#define BMP_TRL_TITLE_CGX		( 1 )
#define BMP_TRL_BTN_NEXT_CGX	( BMP_TRL_TITLE_CGX		 + BMP_TRL_TITLE_W		* BMP_STRING_H )
#define BMP_TRL_BTN_RETURN_CGX	( BMP_TRL_BTN_NEXT_CGX	 + BMP_TRL_BTN_NEXT_W	* BMP_STRING_H )
#define BMP_TRL_TEXT_CGX		( BMP_TRL_BTN_RETURN_CGX + BMP_TRL_BTN_RETURN_W	* BMP_STRING_H )

#define TUTORIAL_TEXT_LINE ( 9 )	// 説明文の行数
#define FONT_BUTTON_PAL ( 3 )		// ボタンフォント用パレット（行）

//--------------------------------------------------------------
///	BMPWIN用 データテーブル
//==============================================================
static const BMPWIN_DAT c_BmpWinList[ BMPWIN_ID_MAX ] =
{
	// -- main --
	{ BG_FRM_M_TEXT, 7,	 2,	BMP_POINT_CAP_W,BMP_STRING_H, FONT_TALK_PAL, BMP_POINT_CAP_CGX, },	// BMPWIN_ID_M_POINT_CAP
	{ BG_FRM_M_TEXT, 4,	 6,	BMP_POINT_MSG_W,BMP_STRING_H, FONT_TALK_PAL, BMP_POINT_MSG_CGX, },	// BMPWIN_ID_M_POINT_MSG
	{ BG_FRM_M_TEXT, 7,	13,	BMP_OPRCAP_W,	BMP_STRING_H, FONT_TALK_PAL, BMP_OPRCAP_CGX, },		// BMPWIN_ID_M_OPRCAP
	{ BG_FRM_M_TEXT, 4,	17,	BMP_OPRMSG_W,	BMP_STRING_H * OPRMSG_LINE, FONT_TALK_PAL, BMP_OPRMSG_01_CGX, }, // BMPWIN_ID_M_OPRMSG_01
	{ BG_FRM_M_TEXT, 25, 1,	BMP_BTN_TRL_W,	BMP_STRING_H, FONT_BUTTON_PAL, BMP_BTN_TRL_CGX, },	// BMPWIN_ID_M_BTN_TRL
	// -- sub --
	{ BG_FRM_S_TEXT, 9,	 3,	BMP_S_MATCH_W,		BMP_STRING_H, FONT_TALK_PAL, BMP_S_MATCH_CGX },		// BMPWIN_ID_S_MATCH
	{ BG_FRM_S_TEXT, 5,	18,	BMP_S_SCORE_CAP_W,	BMP_STRING_H, FONT_TALK_PAL, BMP_S_SCORE_CAP_CGX },	// BMPWIN_ID_S_SCORE_CAP
	{ BG_FRM_S_TEXT, 5,	20,	BMP_S_SCORE_W,		BMP_STRING_H, FONT_TALK_PAL, BMP_S_SCORE_CGX },		// BMPWIN_ID_S_SCORE
	// -- tutorial --
	{ BG_FRM_M_TEXT, 5,	 1,	BMP_TRL_TITLE_W,		BMP_STRING_H, FONT_TALK_PAL, BMP_TRL_TITLE_CGX, },
	{ BG_FRM_M_TEXT, 19, 1,	BMP_TRL_BTN_NEXT_W,		BMP_STRING_H, FONT_BUTTON_PAL, BMP_TRL_BTN_NEXT_CGX, },
	{ BG_FRM_M_TEXT, 26, 1,	BMP_TRL_BTN_RETURN_W,	BMP_STRING_H, FONT_BUTTON_PAL, BMP_TRL_BTN_RETURN_CGX, },
	{ BG_FRM_M_TEXT, 2,	 5,	BMP_TRL_TEXT_W,			BMP_STRING_H * TUTORIAL_TEXT_LINE, FONT_TALK_PAL, BMP_TRL_TEXT_CGX, },
};



//--------------------------------------------------------------------------------------------
/**
 * 初期化関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
PTH_RC EvtStart_InitFunc(PKTHLN_PTR work, void *pParam)
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);
	u8 seq = PTFrame_GetSubSeq(work);

	switch(seq){
	case 0:
		SceneInit(work);
		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 1:
		//OBJ初期化
		InitObj(ptr);
		//BG初期化
		InitBG(ptr->bgl,ptr->HeapID);
		ptr->logo = EvtLogo_Init( ptr->ev_idx, ptr->HeapID );
		EvtLogo_Setup( ptr->logo, ptr->bgl );
		//BGセット
		SetBG(ptr);
		EvtLogo_SetBG( ptr->logo );
		EventBgInit( ptr );
		// 通信アイコンを起動
		WirelessIconEasyPokethlon( NNS_G2D_VRAM_TYPE_2DSUB );
		//OBJの表示
		GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// MAIN DISP OBJ ON
		GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// SUB DISP OBJ ON
		//描画を許可
		PTFrame_SetDraw(work, TRUE);
		//サブシーケンスを初期化
		PTFrame_SetSubSeq(work, 0);
		//初期化終了
		return PTH_RC_END;
	default:
		GF_ASSERT(0);
	}
	return PTH_RC_LOOP;
}

//----------------------------------------------------------------------------
/**
 *	@brief	描画関数
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*pParam		パラメータ
 *
 *	@return	TRUE
 */
//-----------------------------------------------------------------------------
BOOL EvtStart_DrawFunc(PKTHLN_PTR work, void *pParam)
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);
	CATS_Draw( ptr->crp );
	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * 終了関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
BOOL EvtStart_EndFunc(PKTHLN_PTR work, void *pParam)
{
	int i;
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	//アーカイブ開放
	ArchiveDataHandleClose( ptr->arc_ev_title );

	WirelessIconEasyEnd();

	EvtLogo_End( ptr->logo );

	//BMPWIN開放
	MUSEUM_BMPWIN_Delete( ptr->wk_msg, BMPWIN_ID_MAX );

	//BG削除
	for( i=0; i<BG_USE_NUM; i++ )
	{
		GF_BGL_BGControlExit( ptr->bgl, c_BG_UseList[i] );
	}

	//BGL解放
	sys_FreeMemoryEz(ptr->bgl);

	{
		for( i=0; i<OBJ_ID_MAX; i++ )
		{
			if( ptr->cap[i] != NULL )
			{
				CATS_ActorPointerDelete_S( ptr->cap[i] );
				ptr->cap[i] = NULL;
			}
		}

		CATS_ResourceDestructor_S( ptr->csp, ptr->crp );
		CATS_FreeMemory( ptr->csp );
	}

	sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
	sys_HBlankIntrSet( NULL,NULL );		// HBlankセット

	//イベントワーク解放
	PTFrame_FreeEventWork(work);

	// 上下画面を元に戻しておく
	sys.disp3DSW = DISP_3D_TO_MAIN;
	GF_Disp_DispSelect();

	Overlay_UnloadID( FS_OVERLAY_ID(pkthln_common) );

	//ヒープ解放
	sys_DeleteHeap( HEAPID_PT_EVTCALL );

	return TRUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	VBlank処理
 *
 *	@param	void* work	登録したポインタ
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void VBlankFunc( void* work )
{
	EVT_START_PTR ptr = work;

	CATS_RenderOamTrans();
	GF_BGL_VBlankFunc( ptr->bgl );
	OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}

//--------------------------------------------------------------------------------------------
/**
 * VRAM設定		ポケスロンでは、ポケモン表示だけで0x30000必要となる。
 * VRAM_AB(0x40000)でないとはいらん
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetVramBank(void)
{
	GF_BGL_DISPVRAM tbl = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレットM
		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_32_H,		// サブ2DエンジンのBG拡張パレット

		GX_VRAM_OBJ_128_B,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット

		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット

		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &tbl );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BGMの変数をチェック
 *
 *	@param	u8 var_no
 *	@param	check_val
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL CheckBgmVariable( u8 var_no , u8 check_val )
{
	s16 ret;

	Snd_ReadVariableByBgmNo( Snd_NowBgmNoGet(), var_no, &ret );

	if( ret >= check_val )
	{
		return TRUE;
	}

	return FALSE;
}
//-----------------------------------------------------------------------------
/**
 *	@brief	イベントコードを取得
 *
 *	@param	PKTHLN_PTR work
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static u8 GetEventCode( PKTHLN_PTR work )
{
	u8 ret = 0;

	ret = PTFrame_GetEventCode( work );

	HOSAKA_PRINT( "get event code : %d \n", ret );

#ifdef EVT_START_DEBUG_MODE
	// 呼ぶたびに競技コードをインクリメント
	{
		static u8 s_ev_idx = 0;
		ret = s_ev_idx;
		s_ev_idx++;
		if( 10 <= s_ev_idx ){ s_ev_idx = 0; }
	}
#endif

	return ret;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ミュージアムフラグ２の状態を取得
 *
 *	@param	PKTHLN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL GetMuseumFlag( PKTHLN_PTR ptr )
{
	SAVEDATA* sv = PTFrame_GetSaveData( ptr );
	return EventWork_CheckEventFlag( SaveData_GetEventWork(sv), FE_PKTH_MUSEUM02_OPEN );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	初期化処理
 *
 *	@param	EVT_START_PTR* ptr	ワークポインタ
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void SceneInit( PKTHLN_PTR work )
{
	HEAPID	heap_id;
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);
	sys_CreateHeap( HEAPID_POKETHLON, HEAPID_PT_EVTCALL, EVTCALL_HEAP_SIZE );
	heap_id = HEAPID_PT_EVTCALL;

	Overlay_Load( FS_OVERLAY_ID(pkthln_common), OVERLAY_LOAD_NOT_SYNCHRONIZE );

	sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
	sys_HBlankIntrSet( NULL,NULL );		// HBlankセット

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane( 0 );
	GXS_SetVisiblePlane( 0 );

	//VRAMバンク割り当て
	SetVramBank();

	//アプリケーションメモリー
	ptr = PTFrame_AllocEventWork(work, sizeof(EVT_START));
	MI_CpuClear8( ptr, sizeof(EVT_START));

	ptr->arc_ev_title = ArchiveDataHandleOpen( ARC_PKTHEV_TITLE, heap_id );	// アーカイブオープン
	ptr->bgl = GF_BGL_BglIniAlloc(heap_id);	//BGLアロケーション
	ptr->ev_idx = GetEventCode( work ); // イベントIDを設定
	ptr->match = PTFrame_GetEventCounter( work );
	ptr->b_comm = ( PTFrame_GetGameType( work ) == PKTHLN_GAME_COMM );
	ptr->wk_main = work;
	ptr->HeapID = heap_id;

	sys_VBlankFuncChange( VBlankFunc, ptr );	// VBlankセット

	//下画面をメインにする
	sys.disp3DSW = DISP_3D_TO_SUB;
	GF_Disp_DispSelect();

	// 両面を白フェード状態にリセット
	WIPE_SetBrightnessFadeOut( WIPE_FADE_WHITE );

	if( ptr->b_comm )
	{
		// 通信時はミュージアムフラグOFFとする
		ptr->b_draw_score = FALSE;
	}
	else
	{
		ptr->b_draw_score = GetMuseumFlag( work );

#ifdef PM_DEBUG
		// DEBUGボタンと上を押していれば、スコアを表示
		if( (sys.cont & PAD_BUTTON_DEBUG) && (sys.cont & PAD_KEY_UP) )
		{
			ptr->b_draw_score = TRUE;
		}
#endif
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	上画面BGロード：タイトル
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BGLoad_LcdSub_Title( EVT_START_PTR ptr )
{
	// BG2の拡張パレット領域にフォント用パレットを展開
	SystemFontPaletteLoad( PALTYPE_SUB_BG_EX, 0x4000, ptr->HeapID );

	// ロゴ用BGセット
	EvtLogo_SetBG( ptr->logo );

	// Sub LCD
	ArcUtil_HDL_PalSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_NCLR, PALTYPE_SUB_BG, 0, 0, ptr->HeapID );

	ArcUtil_HDL_BgCharSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_lz_NCGR,
			ptr->bgl, BG_FRM_S_BASE, 0, 0, TRUE, ptr->HeapID );

	// スクリーンの読み替え
	if( ptr->b_draw_score )
	{
		ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_sub_high_lz_NSCR,
			ptr->bgl, BG_FRM_S_BASE, 0, 0, TRUE, ptr->HeapID );
	}
	else
	{
		ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_sub_lz_NSCR,
			ptr->bgl, BG_FRM_S_BASE, 0, 0, TRUE, ptr->HeapID );
	}

}

//-----------------------------------------------------------------------------
/**
 *	@brief	上画面BGロード：キャプチャー画像
 *
 *	@param	EVT_START_PTR ptr
 *	@param	ev_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BGLoad_LcdSub_EvCapture( EVT_START_PTR ptr, int ev_idx )
{
	int nclr;
	int ncgr;
	int nscr;

	GF_ASSERT( ev_idx < PKTHLN_EVT_MAX );

	nclr = NARC_pkth_evt_title_bg_evt_t01_NCLR + ev_idx;
	ncgr = NARC_pkth_evt_title_bg_evt_t01_lz_NCGR + ev_idx;
	nscr = NARC_pkth_evt_title_bg_evt_t01_lz_NSCR + ev_idx;

	ArcUtil_HDL_PalSet( ptr->arc_ev_title, nclr, PALTYPE_SUB_BG_EX, 0x6000, 0, ptr->HeapID );
	ArcUtil_HDL_BgCharSet( ptr->arc_ev_title, ncgr, ptr->bgl, BG_FRM_S_EVT, 0, 0, TRUE, ptr->HeapID );
	ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, nscr, ptr->bgl, BG_FRM_S_EVT, 0, 0, TRUE, ptr->HeapID );

	// バックドロップ面を黒くする
	GF_BGL_BackGroundColorSet( GF_BGL_FRAME0_S, 0 );

#if 1
	// アフィンパラメータを初期化
	{
		MtxFx22 mtx;

		mtx._00 = FX32_ONE;
		mtx._01 = 0;
		mtx._10 = 0;
		mtx._11 = FX32_ONE;

		SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup

		GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVT, &mtx, 0, 0 );
		GF_BGL_AffineScrollSet( ptr->bgl, BG_FRM_S_EVT, GF_BGL_SCROLL_Y_SET, 0, &mtx, 0, 0 );
	}
#endif
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BG初期化
 *	@param	GF_BGL_INI* ini
 *	@param	HeapID
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void InitBG( GF_BGL_INI* ini, HEAPID HeapID )
{
	{	// -- BG SYSTEM --
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_5,GX_BG0_AS_2D
		};
		GF_BGL_InitBG(&BGsys_data);
	}

	{
		int i;
		GF_BGL_BGCNT_HEADER bg_data[ BG_USE_NUM ] = {
			// -- MAIN --
			{	// BG_0 ベース
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0000,GX_BG_CHARBASE_0x04000,GX_BG_EXTPLTT_01,
				2,0,0,FALSE
			},
			{	// BG_1 ボタン
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0800,GX_BG_CHARBASE_0x08000,GX_BG_EXTPLTT_01,
				1,0,0,FALSE
			},
			{	// BG_2 テキスト
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x1000,GX_BG_CHARBASE_0x0c000,GX_BG_EXTPLTT_01,
				0,0,0,FALSE
			},
			// -- SUB --
			{	// BG_0 ベース
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0000,GX_BG_CHARBASE_0x04000,GX_BG_EXTPLTT_01,
				3,0,0,FALSE
			},
			{	// BG_1 テキスト
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0800,GX_BG_CHARBASE_0x08000,GX_BG_EXTPLTT_01,
				2,0,0,FALSE
			},
			{	// BG_2 イベント名用アフィンテキスト
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_256,
				GX_BG_SCRBASE_0x1000,GX_BG_CHARBASE_0x10000,GX_BG_EXTPLTT_01,
				0,0,0,FALSE
			},
			{	// BG_3 イベント名(アフィン
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_256,
				GX_BG_SCRBASE_0x1800,GX_BG_CHARBASE_0x14000,GX_BG_EXTPLTT_01,
				1,0,0,FALSE
			},
		};

		for( i=0; i<BG_USE_NUM; i++ )
		{
			GF_BGL_BGControlSet( ini, c_BG_UseList[i], &(bg_data[i]), c_BG_ModeList[i] );
			GF_BGL_ScrClear( ini, c_BG_UseList[i] );
			GF_BGL_ClearCharSet( c_BG_UseList[i], 64, 0, HeapID );
		}
	}

}

//--------------------------------------------------------------------------------------------
/**
 * @brief	BGキャラセット
 * @param	none
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetBG(EVT_START_PTR ptr)
{
	int i;

	//----------------------------------------------------
	// Main LCD
	ArcUtil_HDL_PalSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_NCLR,
			PALTYPE_MAIN_BG, 0, 0, ptr->HeapID );

	// -- base --
	ArcUtil_HDL_BgCharSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_lz_NCGR,
			ptr->bgl, BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_lz_NSCR,
			ptr->bgl, BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	// 非通信時のみボタン表示
	if( ptr->b_comm == FALSE )
	{
		ArcUtil_HDL_BgCharSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_lz_NCGR,
				ptr->bgl, BG_FRM_M_BTN, 0, 0, TRUE, ptr->HeapID );

		ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_button_lz_NSCR,
				ptr->bgl, BG_FRM_M_BTN, 0, 0, TRUE, ptr->HeapID );

	}

	//----------------------------------------------------

	BGLoad_LcdSub_Title( ptr );

	// BMPWIN初期化
	ptr->wk_msg = MUSEUM_BMPWIN_Create( ptr->HeapID, ptr->bgl, BMPWIN_ID_MAX, c_BmpWinList, NARC_msg_pokethlon_dat );

	PrintStaticMessage_Init( ptr );

}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *	@param	ev_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static u16 GetBestScore( EVT_START_PTR ptr, u8 ev_idx )
{
	SAVEDATA* p_sv;
	PKTHLN_SV_DATA_PTR p_pksv;
	const PKTH_EVT_DATA* p_ev;

	p_sv = PTFrame_GetSaveData( ptr->wk_main );
	p_pksv = PkthlnSv_GetSaveData( p_sv );
	p_ev = PkthlnSv_GetEvtDataAlone( p_pksv );

	return p_ev[ ev_idx ].RcMs[0].Record;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メッセージ描画：タイトル
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void PrintStaticMessage_Init( EVT_START_PTR ptr )
{
	u8 ev_idx = ptr->ev_idx;
	u8 match = ptr->match+1;

	// スコアを表示しない場合は場所を移動しておく
	if( ptr->b_draw_score == FALSE )
	{
		MUSEUM_BMPWIN_SetPosY( ptr->wk_msg, BMPWIN_ID_S_MATCH, BG_EVT_COMM_DEF_Y );
	}

	MUSEUM_BMPWIN_Print( ptr->wk_msg, BMPWIN_ID_M_POINT_CAP,	msg_pkthln_tc_point_get_cap, FALSE );
	MUSEUM_BMPWIN_Print( ptr->wk_msg, BMPWIN_ID_M_OPRCAP,		msg_pkthln_tc_operate_cap, FALSE );
	MUSEUM_BMPWIN_PrintAndSetOfs( ptr->wk_msg, BMPWIN_ID_M_POINT_MSG, msg_pkthln_tc_point_get_00 + ev_idx,	BMPWIN_OFS_X, 0 );
	MUSEUM_BMPWIN_PrintAndSetOfs( ptr->wk_msg, BMPWIN_ID_M_OPRMSG_01, msg_pkthln_tc_operate_00_00 + ev_idx*3,	BMPWIN_OFS_X, 0 );
	MUSEUM_BMPWIN_PrintNum( ptr->wk_msg, BMPWIN_ID_S_MATCH, msg_pkthln_tc_match, match, 1, 0 );

	// 非通信時のみボタン表示
	if( ptr->b_comm == FALSE )
	{
		MUSEUM_BMPWIN_PrintEx( ptr->wk_msg, BMPWIN_ID_M_BTN_TRL, msg_pkthln_tc_btn_tutorial, FALSE, 0, FONT_TOUCH );
	}

	EvtLogo_Print( ptr->logo );

	// スコア表示
	if( ptr->b_draw_score )
	{
		u16 score = GetBestScore( ptr, ptr->ev_idx );

		// データが無ければ0として扱う(念のため)
		if( score == REC_NO_DATA )
		{
			score = 0;
		}

		if( ptr->ev_idx == PKTHLN_EVT_DASH )
		{
			WORDSET* wset = MUSEUM_BMPWIN_GetWordset( ptr->wk_msg );

#ifdef PM_DEBUG
			GF_ASSERT( score/30 < 1000 );
#endif

			// ハードルはxxx:xになるので例外処理
			WORDSET_RegisterNumber( wset, 0, (score/30), 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
			WORDSET_RegisterNumber( wset, 1, (score%30)*10/30, 1, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
		}
		else if( ptr->ev_idx == PKTHLN_EVT_RUN )
		{
			// マラソンは1024で割る
			MUSEUM_BMPWIN_RegistNum( ptr->wk_msg, score/1024, 2, 0 );
			MUSEUM_BMPWIN_RegistNum( ptr->wk_msg, (score%1024)*10/1024, 1, 1 );
		}
		else
		{
			MUSEUM_BMPWIN_RegistNum( ptr->wk_msg, score, 3, 0 );
		}

		MUSEUM_BMPWIN_Print( ptr->wk_msg, BMPWIN_ID_S_SCORE_CAP,	msg_pkthln_tc_score_cap, FALSE );
		MUSEUM_BMPWIN_PrintRegStr( ptr->wk_msg, BMPWIN_ID_S_SCORE,	msg_pkthln_tc_score_00 + ev_idx );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メッセージ描画：ルールについて
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void PrintStaticMessage_Rule( EVT_START_PTR ptr )
{
	int text_gmm_idx = msg_pkthln_tc_operate_00_01 + ptr->ev_idx * 3;
	MUSEUM_BMPWIN_Print( ptr->wk_msg, BMPWIN_TUTORIAL_ID_TITLE,			msg_pkthln_tc_cap_rule,		FALSE );
	MUSEUM_BMPWIN_PrintEx( ptr->wk_msg, BMPWIN_TUTORIAL_ID_BTN_NEXT,	msg_pkthln_tc_btn_control,	FALSE, 0, FONT_TOUCH );
	MUSEUM_BMPWIN_PrintEx( ptr->wk_msg, BMPWIN_TUTORIAL_ID_BTN_RETURN,	msg_pkthln_tc_btn_return,	FALSE, 0, FONT_TOUCH );
	MUSEUM_BMPWIN_PrintAndSetOfs( ptr->wk_msg, BMPWIN_TUTORIAL_ID_TEXT,	text_gmm_idx, BMPWIN_OFS_X, 0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メッセージ描画：そうさのしかた
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void PrintStaticMessage_Control( EVT_START_PTR ptr )
{
	int text_gmm_idx = msg_pkthln_tc_operate_00_02 + ptr->ev_idx * 3;
	MUSEUM_BMPWIN_Print( ptr->wk_msg, BMPWIN_TUTORIAL_ID_TITLE,			msg_pkthln_tc_cap_control,	FALSE );
	MUSEUM_BMPWIN_PrintEx( ptr->wk_msg, BMPWIN_TUTORIAL_ID_BTN_NEXT,	msg_pkthln_tc_btn_rule,		FALSE, 0, FONT_TOUCH );
	MUSEUM_BMPWIN_PrintEx( ptr->wk_msg, BMPWIN_TUTORIAL_ID_BTN_RETURN,	msg_pkthln_tc_btn_return,	FALSE, 0, FONT_TOUCH );
	MUSEUM_BMPWIN_PrintAndSetOfs( ptr->wk_msg, BMPWIN_TUTORIAL_ID_TEXT,	text_gmm_idx, BMPWIN_OFS_X, 0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ 初期化処理
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void InitObj( EVT_START_PTR ptr )
{
	TCATS_RESOURCE_NUM_LIST crnl = { CHR_ID_MAX, PAL_ID_MAX, CEL_ID_MAX, ANM_ID_MAX, 0 };
	CATS_SYS_PTR	csp;

	TCATS_OAM_INIT	coi = {
		0, 126,
		0, 32,
		1, 126,
		0, 32,
	};

	TCATS_CHAR_MANAGER_MAKE ccmm = {
		0,	// dummy
		1024*128,
		1024*16,
		GX_OBJVRAMMODE_CHAR_1D_64K,
		GX_OBJVRAMMODE_CHAR_1D_256K,
	};
	ccmm.num = OBJ_ID_MAX;

	ptr->csp = CATS_AllocMemory( ptr->HeapID );
	ptr->crp = CATS_ResourceCreate( ptr->csp );

	CATS_SystemInit( ptr->csp, &coi, &ccmm, 32 );
	CATS_ClactSetInit( ptr->csp, ptr->crp, OBJ_ID_MAX );
	CATS_ResourceManagerInit( ptr->csp, ptr->crp, &crnl );

	GF_Disp_GX_VisibleControl(  GX_PLANEMASK_OBJ, VISIBLE_ON );		// MAIN DISP OBJ ON
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// SUB DISP OBJ ON

	//サブサーフェースの距離を設定
	CLACT_U_SetSubSurfaceMatrix( CATS_EasyRenderGet( ptr->csp ), 0, OBJ_DISTANCE );

	//OBJリソースロード
	ObjLoadRes( ptr );
	ObjAddCommon( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ リソースロード
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void ObjLoadRes( EVT_START_PTR ptr )
{
	CATS_SYS_PTR	csp = ptr->csp;
	CATS_RES_PTR	crp = ptr->crp;

	// -- pkth_title --
	CATS_LoadResourcePlttArcH( csp, crp, ptr->arc_ev_title,
			NARC_pkth_evt_title_pkth_title_NCLR, FALSE, 16, NNS_G2D_VRAM_TYPE_2DMAIN, PAL_ID_M_COMMON );

	CATS_LoadResourceCharArcH( csp, crp, ptr->arc_ev_title,
			NARC_pkth_evt_title_pkth_title_lz_NCGR, TRUE, NNS_G2D_VRAM_TYPE_2DMAIN, CHR_ID_M_COMMON );

	CATS_LoadResourceCellArcH( csp, crp, ptr->arc_ev_title,
			NARC_pkth_evt_title_pkth_title_lz_NCER, TRUE, CEL_ID_COMMON );

	CATS_LoadResourceCellAnmArcH( csp, crp,  ptr->arc_ev_title,
			NARC_pkth_evt_title_pkth_title_lz_NANR, TRUE, ANM_ID_COMMON );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ 更新処理
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void ObjProc( EVT_START_PTR ptr )
{
	CATS_ACT_PTR cap = ptr->cap[ OBJ_ID_M_OPERATE ];

	if( CATS_ObjectAnimeActiveCheckCap( cap ) == FALSE )
	{
		ptr->anm_seq++;
		if( ptr->anm_seq >= ANM_OPERATE_MAX ){ ptr->anm_seq = 0; }
		ObjSetOperateAnm( ptr );
//		HOSAKA_PRINT( "change anm :ev_idx:%d, anm_seq:%d \n",ptr->ev_idx, ptr->anm_seq );
	}
}


//--------------------------------------------------------------
///	OBJ座標モード
//==============================================================
enum {
	OBJ_VIEW_ID_TITLE = 0,
	OBJ_VIEW_ID_TUTORIAL,
	OBJ_VIEW_ID_MAX,
};

//--------------------------------------------------------------
///	OBJ座標 テーブル
//==============================================================
static const s16 g_ObjPos[OBJ_VIEW_ID_MAX][OBJ_ID_COMMON_MAX][2] =
{
	// OBJ_VIEW_ID_TITLE
	{
		{ 4*8,	 3*8 },
		{ 4*8,	14*8 },
		{ 26*8, 14*8 },
		{ 29*8-6, 23*8-4 },
	},

	// OBJ_VIEW_ID_TUTORIAL
	{
		{ 2*8, 2*8 },
		{ 2*8, 2*8 },
		{ 25*8, 20*8 },
		{ 29*8-6, 23*8-4 },
	},
};

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ位置を設定
 *
 *	@param	EVT_START_PTR ptr
 *	@param	view_idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_SetViewMode( EVT_START_PTR ptr, int view_idx )
{
	int i;

	for( i=0; i<OBJ_ID_MAX; i++ )
	{
		CATS_ObjectPosSetCap_SubSurface( ptr->cap[i], g_ObjPos[view_idx][i][0], g_ObjPos[view_idx][i][1], OBJ_DISTANCE );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBjRestart( EVT_START_PTR ptr )
{
	ptr->anm_seq = 0;
	ObjSetOperateAnm( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ 汎用OBJ追加 (ev_idxが設定された後に呼ぶこと)
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void ObjAddCommon( EVT_START_PTR ptr )
{
	static TCATS_OBJECT_ADD_PARAM_S	common_prm[ OBJ_ID_COMMON_MAX ] =
	{
		{	// OBJ_ID_M_POINT
			0, 0, 0,
			NANR_pkth_title_point_icon, 0, TCATS_ADD_S_PAL_AUTO, NNS_G2D_VRAM_TYPE_2DMAIN,
			{ CHR_ID_M_COMMON, PAL_ID_M_COMMON, CEL_ID_COMMON, ANM_ID_COMMON, 0, 0 }, 0, FALSE,
		},
		{	// OBJ_ID_M_PEN
			0, 0, 0,
			NANR_pkth_title_pen_icon, 0, TCATS_ADD_S_PAL_AUTO, NNS_G2D_VRAM_TYPE_2DMAIN,
			{ CHR_ID_M_COMMON, PAL_ID_M_COMMON, CEL_ID_COMMON, ANM_ID_COMMON, 0, 0 }, 0, FALSE,
		},
		{	// OBJ_ID_M_OPERATE
			0, 0, 0,
			0, 0, TCATS_ADD_S_PAL_AUTO, NNS_G2D_VRAM_TYPE_2DMAIN,
			{ CHR_ID_M_COMMON, PAL_ID_M_COMMON, CEL_ID_COMMON, ANM_ID_COMMON, 0, 0 }, 0, FALSE,
		},
		{	// OBJ_ID_M_TOUCH_ICON
			0, 0, 0,
			NANR_pkth_title_touch_icon, 0, TCATS_ADD_S_PAL_AUTO, NNS_G2D_VRAM_TYPE_2DMAIN,
			{ CHR_ID_M_COMMON, PAL_ID_M_COMMON, CEL_ID_COMMON, ANM_ID_COMMON, 0, 0 }, 0, FALSE,
		},
	};

	int i;

	// COMMON OBJ初期化
	for( i=0; i<OBJ_ID_COMMON_MAX; i++ )
	{
		CATS_SYS_PTR	csp = ptr->csp;
		CATS_RES_PTR	crp = ptr->crp;

		common_prm[i].x = g_ObjPos[OBJ_VIEW_ID_TITLE][i][0];
		common_prm[i].y = g_ObjPos[OBJ_VIEW_ID_TITLE][i][1];

		ptr->cap[i] = CATS_ObjectAdd_S_SubDistance( csp, crp, &common_prm[i], OBJ_DISTANCE );
		CATS_ObjectAutoAnimeSetCap( ptr->cap[ i ], TRUE );
	}

	// 説明OBJのアニメ設定
	CATS_ObjectAutoAnimeSetCap( ptr->cap[ OBJ_ID_M_OPERATE ], FALSE );
	ObjSetOperateAnm( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	説明OBJのアニメを設定
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void ObjSetOperateAnm( EVT_START_PTR ptr )
{
	static const c_anm_operate_tbl[][ ANM_OPERATE_MAX ] =
	{
		{ NANR_pkth_title_dash,		NANR_pkth_title_dash },
		{ NANR_pkth_title_steal,	NANR_pkth_title_steal },
		{ NANR_pkth_title_push,		NANR_pkth_title_push },
		{ NANR_pkth_title_break,	NANR_pkth_title_break },
		{ NANR_pkth_title_catch,	NANR_pkth_title_catch },
		{ NANR_pkth_title_jump,		NANR_pkth_title_jump },
		{ NANR_pkth_title_run,		NANR_pkth_title_run },
		{ NANR_pkth_title_drop,		NANR_pkth_title_drop },
		{ NANR_pkth_title_throw,	NANR_pkth_title_throw },
		{ NANR_pkth_title_shot,		NANR_pkth_title_shot },
	};

	CATS_ObjectAnimeSeqSetCap( ptr->cap[ OBJ_ID_M_OPERATE ], c_anm_operate_tbl[ ptr->ev_idx ][ ptr->anm_seq ] );
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void EventBgInit( EVT_START_PTR ptr )
{
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_BG2, VISIBLE_OFF );
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_OFF );
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void EventBgStartUp( EVT_START_PTR ptr )
{
	// アフィン初期設定
	{
		MtxFx22 mtx;
		fx32 scale;
		u8 dec_y = 0;

		if( ptr->b_draw_score == FALSE )
		{
			dec_y = EVENT_BG_DIFF_Y;
		}

		scale = FX32_CONST( 1.0/BG_IN_FRAME );
		mtx._00 = scale;
		mtx._01 = 0;
		mtx._10 = 0;
		mtx._11 = scale;

		SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup
		GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVT, &mtx, 128, 96 );
		GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVTMSG, &mtx, 128, 96 );
		GF_BGL_AffineScrollSet( ptr->bgl, BG_FRM_S_EVT, GF_BGL_SCROLL_Y_DEC, dec_y, &mtx, 128, 96 );
		GF_BGL_AffineScrollSet( ptr->bgl, BG_FRM_S_EVTMSG, GF_BGL_SCROLL_Y_DEC, dec_y, &mtx, 128, 96 );
	}

	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_BG2, VISIBLE_ON );
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_ON );

	ptr->Counter = 0;
	ptr->b_bg_move = TRUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void EventBgProc( EVT_START_PTR ptr )
{
	MtxFx22 mtx;
	fx32 scale;

	ptr->Counter++;

	scale = (ptr->Counter << FX32_SHIFT) / BG_IN_FRAME;

	mtx._00 = scale;
	mtx._01 = 0;
	mtx._10 = 0;
	mtx._11 = scale;

	SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup
	GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVT, &mtx, 128, 96 );
	GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVTMSG, &mtx, 128, 96 );

	HOSAKA_PRINT("scale:%x cnt:%d \n",scale, ptr->Counter);

	if( ptr->Counter >= BG_IN_FRAME )
	{
		ptr->Counter = 0;
		ptr->b_bg_move = FALSE;
	}

}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	PKTHLN_PTR work
 *	@param	next_phase
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phase_SetNextReq( PKTHLN_PTR work, int next_phase )
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	// ホワイトアウト開始
	WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT, WIPE_FADE_WHITE, 4, 1, ptr->HeapID );

	// @@@ フェイズ遷移 アサーションするならココ

	ptr->next_phase = next_phase;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	PKTHLN_PTR work
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static BOOL Phase_ChangeProc( PKTHLN_PTR work )
{
	return WIPE_SYS_EndCheck();
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phase_Load_Title( EVT_START_PTR ptr )
{
	ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base_lz_NSCR,
						ptr->bgl, BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	BGLoad_LcdSub_Title( ptr );

	// OBJ位置調整
	OBJ_SetViewMode( ptr, OBJ_VIEW_ID_TITLE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_POINT ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_PEN ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_OPERATE ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_TOUCH_ICON ], CATS_ENABLE_TRUE );

	// BG切替
	GF_BGL_VisibleSet( BG_FRM_S_TEXT, VISIBLE_ON );
	GF_BGL_VisibleSet( BG_FRM_S_EVTMSG, VISIBLE_ON );
	GF_BGL_VisibleSet( BG_FRM_S_BASE, VISIBLE_ON );
	GF_BGL_VisibleSet( BG_FRM_M_BTN, VISIBLE_ON );

	PrintStaticMessage_Init( ptr );

	// アフィン設定
	{
		MtxFx22 mtx;
		int dec_y = 0;

		if( ptr->b_draw_score == FALSE )
		{
			dec_y = -EVENT_BG_DIFF_Y;
		}

		mtx._00 = FX32_ONE;
		mtx._01 = 0;
		mtx._10 = 0;
		mtx._11 = FX32_ONE;

		SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup

		GF_BGL_AffineSet( ptr->bgl, BG_FRM_S_EVT, &mtx, 0, 0 );
		GF_BGL_AffineScrollSet( ptr->bgl, BG_FRM_S_EVT, GF_BGL_SCROLL_Y_SET, dec_y, &mtx, 0, 0 );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phase_Load_Rule( EVT_START_PTR ptr )
{
	BGLoad_LcdSub_EvCapture( ptr, ptr->ev_idx );

	ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base2_lz_NSCR,
						ptr->bgl, BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	// OBJ位置調整
	OBJ_SetViewMode( ptr, OBJ_VIEW_ID_TUTORIAL );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_POINT ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_PEN ], CATS_ENABLE_FALSE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_OPERATE ], CATS_ENABLE_FALSE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_TOUCH_ICON ], CATS_ENABLE_FALSE );

	// BG切替
	GF_BGL_VisibleSet( BG_FRM_S_TEXT, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_S_EVTMSG, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_S_BASE, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_M_BTN, VISIBLE_OFF );

	PrintStaticMessage_Rule( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	EVT_START_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phase_Load_Control( EVT_START_PTR ptr )
{
	BGLoad_LcdSub_EvCapture( ptr, ptr->ev_idx );

	ArcUtil_HDL_ScrnSet( ptr->arc_ev_title, NARC_pkth_evt_title_bg_base2_lz_NSCR,
						ptr->bgl, BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	// OBJ位置調整
	OBJ_SetViewMode( ptr, OBJ_VIEW_ID_TUTORIAL );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_POINT ], CATS_ENABLE_FALSE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_PEN ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_OPERATE ], CATS_ENABLE_TRUE );
	CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_TOUCH_ICON ], CATS_ENABLE_FALSE );

	// BG切替
	GF_BGL_VisibleSet( BG_FRM_S_TEXT, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_S_EVTMSG, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_S_BASE, VISIBLE_OFF );
	GF_BGL_VisibleSet( BG_FRM_M_BTN, VISIBLE_OFF );

	PrintStaticMessage_Control( ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	PKTHLN_PTR work
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Phase_Init( PKTHLN_PTR work )
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	// 共通初期化処理
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_M_BASE );
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_M_TEXT );
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_S_BASE );
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_S_TEXT );
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_S_EVTMSG );
	GF_BGL_ScrClear( ptr->bgl, BG_FRM_S_EVT );

	OBjRestart( ptr );

	// シーン毎の初期化処理
	switch( ptr->next_phase )
	{
		case EVT_START_PHASE_TITLE :
			Phase_Load_Title( ptr );
			WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN, WIPE_FADE_WHITE, 4, 1, ptr->HeapID );
			HOSAKA_PRINT( "set title \n");
			break;

		case EVT_START_PHASE_RULE :
			Phase_Load_Rule( ptr );
			HOSAKA_PRINT( "set rule \n");
			break;

		case EVT_START_PHASE_CONTROL :
			Phase_Load_Control( ptr );
			HOSAKA_PRINT( "set control \n");
			break;

		default : GF_ASSERT(0);
	}

	PTFrame_SetNextFuncTblIdx( work, ptr->next_phase );
}


//----------------------------------------------------------------------------
/**
 *	@brief		アプリメインシーケンス
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@return	BOOL		TRUE: 終了	FALSE:継続
 */
//-----------------------------------------------------------------------------
static BOOL EVT_START_Func_Phase_Init(PKTHLN_PTR work, u8 *seq)
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	ObjProc( ptr );

	switch( (*seq) )
	{
	case 0:
		//BGM再生
		Snd_BgmPlay( SEQ_GS_PT_TITLE );
		(*seq)++;	//次のシーケンスへ
		break;

	case 1:
		if( CheckBgmVariable( 0, 0 ) )
		{
			//フェードイン
			WIPE_SYS_Start(	WIPE_PATTERN_S, WIPE_TYPE_FADEIN,
						WIPE_TYPE_FADEIN, WIPE_FADE_WHITE,
						WIPE_DEF_SYNC, WIPE_DEF_SYNC, ptr->HeapID );

			(*seq)++;	//次のシーケンスへ
		}
		break;
	case 2:
		if( CheckBgmVariable( 0, 1 ) )
		{
			EventBgStartUp( ptr );
			(*seq)++;	//次のシーケンスへ
		}
		break;
	case 3:
		// BG移動
		if( ptr->b_bg_move )
		{
			EventBgProc( ptr );
		}
		else if( CheckBgmVariable( 0, 3 ) )
		{
			//フェードイン
			WIPE_SYS_Start(	WIPE_PATTERN_M, WIPE_TYPE_FADEIN,
						WIPE_TYPE_FADEIN, WIPE_FADE_WHITE,
						WIPE_DEF_DIV*2, WIPE_DEF_SYNC, ptr->HeapID );

			//説明OBJアニメ開始
			CATS_ObjectAutoAnimeSetCap( ptr->cap[ OBJ_ID_M_OPERATE ], TRUE );
			//タッチアイコン 非通信なら表示
			CATS_ObjectEnableCap( ptr->cap[ OBJ_ID_M_TOUCH_ICON ], (ptr->b_comm == 0) );

			//次のシーケンスへ
			(*seq)++;
		}
		break;
	case 4:
		//フェードイン待ち
		if( WIPE_SYS_EndCheck() ){
			// 通信時と非通信時で切替
			if( ptr->b_comm )
			{
				// 通信ウェイトへ
				ptr->Counter = 0;
				(*seq)++;
			}
			else
			{
				// チュートリアルフェイズへ
				// 初回はワイプなしなので直接移動
				PTFrame_SetNextFuncTblIdx( work, EVT_START_PHASE_TITLE );
			}
		}
		break;
	case 5:
		ptr->Counter++;
		if( ptr->Counter >= END_WAIT )
		{
			// 終了フェイズへ
			PTFrame_SetNextFuncTblIdx( work, EVT_START_PHASE_END );
		}
		break;

	default:
		GF_ASSERT(0);
	}

#ifdef PM_DEBUG
	// デバッグスキップ
	if( sys.trg == PAD_BUTTON_X )
	{
		// ワイプ状態を念のため解除
		WIPE_Reset( WIPE_DISP_MAIN );
		WIPE_Reset( WIPE_DISP_SUB );
		WIPE_SYS_ExeEnd();
		return TRUE;
	}
#endif
	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	通信時タイトル フェイズ
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@retval	BOOL		TRUE: 終了	FALSE:継続
 */
//-----------------------------------------------------------------------------
static BOOL EVT_START_Func_Phase_Title(PKTHLN_PTR work, u8 *seq)
{
	static const RECT_HIT_TBL touch_tbl[]={
		{    0,  5*8, 24*8, 32*8, }, // くわしく
		{ 19*8, 23*8, 24*8, 32*8, }, // START
		{TP_HIT_END,0,0,0},		// 終了データ
	};

	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);
	int touch_result;

	ObjProc( ptr );

	switch( *seq )
	{
	case 0 :
		if( WIPE_SYS_EndCheck() == 0 ){ break; }

		// ボタンとの当たり判定
		touch_result = GF_TP_RectHitTrg( touch_tbl );

		if( touch_result != RECT_HIT_NONE )
		{
			switch( touch_result )
			{
				case 0:
					// くわしく
					Snd_SePlay( SE_DECIDE );
					Phase_SetNextReq( work, EVT_START_PHASE_RULE );
					break;
				case 1:
					// START
					PTFrame_SetNextFuncTblIdx( work, EVT_START_PHASE_END );
					break;
				default: GF_ASSERT(0);
			}

			(*seq)++;
		}
		break;

	case 1 :
		if( Phase_ChangeProc( work ) )
		{
			Phase_Init( work );
		}
		break;

	default : GF_ASSERT(0);
	}

#ifdef PM_DEBUG
	// デバッグスキップ
	if( sys.trg == PAD_BUTTON_X )
	{
		// ワイプ状態を念のため解除
		WIPE_Reset( WIPE_DISP_MAIN );
		WIPE_Reset( WIPE_DISP_SUB );
		WIPE_SYS_ExeEnd();
		return TRUE;
	}
#endif

	return FALSE;

}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@retval	BOOL		TRUE: 終了	FALSE:継続
 */
//-----------------------------------------------------------------------------
static BOOL EVT_START_Func_Phase_Rule(PKTHLN_PTR work, u8 *seq)
{
	static const RECT_HIT_TBL touch_tbl[]={
		{ 0, 5*8, 18*8, 25*8, },
		{ 0, 5*8, 25*8, 32*8, },
		{TP_HIT_END,0,0,0},		// 終了データ
	};

	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	ObjProc( ptr );

	switch( *seq )
	{
		case 0 :
			WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN, WIPE_FADE_WHITE, 4, 1, ptr->HeapID );
			(*seq)++;
			/* fallthrow */

		case 1 :
			if( WIPE_SYS_EndCheck() )
			{
				int tp_ret = GF_TP_RectHitTrg( touch_tbl );

				// ボタン当たり判定
				if( tp_ret == 0 )
				{
					Snd_SePlay( SE_DECIDE );
					Phase_SetNextReq( work, EVT_START_PHASE_CONTROL );
					(*seq)++;
				}
				else if( tp_ret == 1 )
				{
					Snd_SePlay( SE_DECIDE );
					Phase_SetNextReq( work, EVT_START_PHASE_TITLE );
					(*seq)++;
				}
			}
			break;

		case 2 :
			if( Phase_ChangeProc( work ) )
			{
				Phase_Init( work );
			}
			break;

		default : GF_ASSERT(0);
	}
	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@retval	BOOL		TRUE: 終了	FALSE:継続
 */
//-----------------------------------------------------------------------------
static BOOL EVT_START_Func_Phase_Control(PKTHLN_PTR work, u8 *seq)
{
	static const RECT_HIT_TBL touch_tbl[]={
		{ 0, 5*8, 18*8, 25*8, },
		{ 0, 5*8, 25*8, 32*8, },
		{TP_HIT_END,0,0,0},		// 終了データ
	};

	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	ObjProc( ptr );

	switch( *seq )
	{
		case 0 :
			WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN, WIPE_FADE_WHITE, 4, 1, ptr->HeapID );
			(*seq)++;
			/* fallthrow */

		case 1 :
			if( WIPE_SYS_EndCheck() )
			{
				int tp_ret = GF_TP_RectHitTrg( touch_tbl );

				// ボタン当たり判定
				if( tp_ret == 0 )
				{
					Snd_SePlay( SE_DECIDE );
					Phase_SetNextReq( work, EVT_START_PHASE_RULE );
					(*seq)++;
				}
				else if( tp_ret == 1 )
				{
					Snd_SePlay( SE_DECIDE );
					Phase_SetNextReq( work, EVT_START_PHASE_TITLE );
					(*seq)++;
				}
			}
			break;

		case 2 :
			if( Phase_ChangeProc( work ) )
			{
				Phase_Init( work );
			}
			break;

		default : GF_ASSERT(0);
	}
	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@retval	BOOL		TRUE: 終了	FALSE:継続
 */
//-----------------------------------------------------------------------------
static BOOL EVT_START_Func_Phase_End(PKTHLN_PTR work, u8 *seq)
{
	EVT_START_PTR ptr = PTFrame_GetEventWorkPtr(work);

	ObjProc( ptr );

	switch( (*seq) )
	{
	case 0:
		if( PTFrame_GetEventCounter(work) == 0 ) {
			// 最初の競技だけはOPのバンクで鳴らす必要がある
			Snd_SePlay( SEQ_SE_GS_GAMENFADEOPED );
		} else {
			Snd_SePlay( SEQ_SE_GS_GAMENFADE );
		}

		Snd_BgmFadeOut( 0, WIPE_DEF_DIV*4 );

		//フェードアウト
		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT,
					WIPE_TYPE_FADEOUT, WIPE_FADE_WHITE,
					WIPE_DEF_DIV*4, WIPE_DEF_SYNC, ptr->HeapID );

		(*seq)++;
		break;

	case 1:
		if( WIPE_SYS_EndCheck() ){
			return TRUE;
		}
		break;
	}
	return FALSE;
}
